/*
 * kkScanWindow.java
 *
 * Created on December 23, 2006, 4:27 PM
 */


//FIX ME : Hide DrivesPanel in the case of linux and relayout the components.
//FIX ME : After a file/folder is removed, the content of the serial field in files table aligns
//         to the right instead of center position.

//FIXME: What if no drives get detected ?
//FIXED : Error message will be popped up.

package kkWindows;

import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.table.*;

import java.awt.event.*;
import javax.swing.event.*;
import java.awt.*;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;


import stec.sfc.Win32.Drive;
import stec.sfc.Win32.DriveType;

/**
 *
 * @author  Kowshik
 */
public class kkScanWindow extends javax.swing.JDialog {
    
    /** Creates new form kkScanWindow */
    public static native String isMaliciousJ(String file);
    public static native void destroyJ();
    public static native int initializeJ();
    
    public ScanManager<Integer,Object> bgWorker;
    public kkScanWindow(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        // if( (System.getProperty("os.name").indexOf("windows")!=-1) || (System.getProperty("os.name").indexOf("Windows")!=-1) )
        loadDriveTable();
        driveTModel=new commonTableModel(drivesData,new String[]{"","Disk","Type"},commonTableModel.DRIVES_TABLE);
        
        initComponents();
        
        //This is used to initialise the other data structures that are related to filesTable
        //------------------------------------------------------------------------------------
        filesList=new LinkedList();
        filesChooser=new JFileChooser();
        accesoryPanel accessory = new accesoryPanel(filesChooser,filesList,filesTable);
        filesChooser.setAccessory(accessory);
        filesChooser.setDialogTitle("Select Files or Folders");
        filesChooser.addPropertyChangeListener
                (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY,
                accessory);
        //-------------------------------------------------------------------------------------
        
        //The following code sets the properties of filesTable and scrollPane objs.
        //----------------------------------------------------------------
        filesTable.setModel(new DefaultTableModel(null,new Object[]{"Serial","","List Of Files"}));
        initFilesTableProperties(filesTable);
        ListSelectionModel rowSM = filesTable.getSelectionModel();
        rowSM.addListSelectionListener(new TableSelectionListener());
        //----------------------------------------------------------------
        
        //The following code sets the properties of driveTable and scrollPane objs.
        //----------------------------------------------------------------
        
        drivesTable.getParent().setBackground(Color.white);
        
        drivesTable.setSelectionBackground(Color.WHITE);
        drivesTable.setSelectionForeground(Color.BLUE);
        drivesTable.setFocusable(false);
        
        drivesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        //Setting the width of the two columns
        TableColumn column=drivesTable.getColumnModel().getColumn(0);
        column.setPreferredWidth(50);
        column=drivesTable.getColumnModel().getColumn(1);
        column.setPreferredWidth(100);
        column=drivesTable.getColumnModel().getColumn(2);
        column.setPreferredWidth(300);
        
        drivesTable.setRowHeight(40);
        
        //-----------------------------------------------------------------------------------------------------------
        
        //Adding listeners to check boxes that allow the user to selct local or removable drives.
        
        
        
        chBoxLocalDrives.addItemListener(new chBoxListener());
        chBoxRemovableDrives.addItemListener(new chBoxListener());
        buttonSelectAllDrives.addActionListener(new drivesButtonListener());
        buttonDeselectAllDrives.addActionListener(new drivesButtonListener());
        buttonAdd.addActionListener(new AddDeleteButtonListener());
        buttonDelete.addActionListener(new AddDeleteButtonListener());
        buttonSelectAllFiles.addActionListener(new filesButtonListener());
        buttonDeselectAllFiles.addActionListener(new filesButtonListener());
        
        bgWorker=new ScanManager(this);
        
        
        
        scanButton.addActionListener(new scanButtonListener(this));
        
        
        
        
    }
    
    private void loadDriveTable(){
        
        java.io.File[] driveNames=java.io.File.listRoots();
        Drive drive;
        
        String[] driveTypes=new String[driveNames.length];
        
        int driveIter;
        Vector<Integer> accessibleDrives=new Vector<Integer>(driveNames.length);
        
        for(driveIter=0 ; driveIter < driveNames.length ; driveIter++){
            
            try{
                drive=new Drive(driveNames[driveIter].getPath());
                if(drive.getType() == DriveType.CDROM){
                    driveTypes[driveIter]="CD ROM Drive";
                } else if(drive.getType()== DriveType.FIXED){
                    driveTypes[driveIter]="Hard Disk Drive";
                } else if(drive.getType()== DriveType.REMOVABLE){
                    driveTypes[driveIter]="Removable Drive";
                }
                
                accessibleDrives.add(driveIter);
                
            } catch(stec.sfc.Win32.Win32Exception e){
                //System.out.println("Cannot access drive : "+driveNames[driveIter]+"\n");
            }
        }
        
        drivesData=new Object[accessibleDrives.size()][3];
        
        Integer temp;
        int i=0;
        
        for(Iterator<Integer> iter= accessibleDrives.iterator(); iter.hasNext() ; i++){
            temp=iter.next();
            drivesData[i][0]=new Boolean(true);
            drivesData[i][1]=driveNames[temp.intValue()].getPath();
            drivesData[i][2]=driveTypes[temp.intValue()];
            
            System.out.println(driveNames[temp.intValue()].getPath() + "=" + drivesData[i][2] );
            
        }
        
    }
    
    static void initFilesTableProperties(JTable filesTable){
        
        filesTable.getParent().setBackground(Color.white);
        
        filesTable.setSelectionBackground(Color.WHITE);
        filesTable.setSelectionForeground(Color.BLUE);
        filesTable.setFocusable(false);
        
        //Setting the width of the columns
        TableColumn column=filesTable.getColumnModel().getColumn(0);
        //column.setCellRenderer(new cellRenderer());
        column.setPreferredWidth(50);
        column=filesTable.getColumnModel().getColumn(1);
        column.setPreferredWidth(50);
        column=filesTable.getColumnModel().getColumn(2);
        column.setCellRenderer(new cellRenderer());
        column.setPreferredWidth(300);
        
        filesTable.setRowHeight(40);
    }
    
    private Vector<String> getTargets() {
        
        Vector<String> driveTargets=null,fileTargets=null ;
        
        commonTableModel model = (commonTableModel)drivesTable.getModel();
        driveTargets= model.getTargets();
        
        if(filesTable.getModel() instanceof commonTableModel){
            
            fileTargets=((commonTableModel)(filesTable.getModel())).getTargets();
        }
        System.out.println(driveTargets+" "+fileTargets);
        
        if(fileTargets == null)
            return driveTargets;
        else if(driveTargets == null)
            return fileTargets;
        else if(fileTargets==null && driveTargets==null)
            return null;
        
        
        
        for(int i=0;i<fileTargets.size();i++)
            driveTargets.add(fileTargets.get(i));
        
        driveTargets.trimToSize();
        return driveTargets;
        
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        kkScanner_Tabber = new javax.swing.JTabbedPane();
        TargetTab = new javax.swing.JPanel();
        DrivesPanel = new javax.swing.JPanel();
        drivesScrollPane = new javax.swing.JScrollPane();
        drivesTable = new javax.swing.JTable();
        chBoxLocalDrives = new javax.swing.JCheckBox();
        chBoxRemovableDrives = new javax.swing.JCheckBox();
        buttonSelectAllDrives = new javax.swing.JButton();
        buttonDeselectAllDrives = new javax.swing.JButton();
        FilesPanel = new javax.swing.JPanel();
        buttonAdd = new javax.swing.JButton();
        buttonDelete = new javax.swing.JButton();
        buttonSelectAllFiles = new javax.swing.JButton();
        buttonDeselectAllFiles = new javax.swing.JButton();
        filesScrollPane = new javax.swing.JScrollPane();
        filesTable = new javax.swing.JTable();
        ScanningTab = new javax.swing.JPanel();
        textAreaScrollPane = new javax.swing.JScrollPane();
        textArea = new javax.swing.JTextArea();
        scanButton = new javax.swing.JButton();
        stopButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Scanner");
        setModal(true);
        DrivesPanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        TitledBorder titleDisks=BorderFactory.createTitledBorder(BorderFactory.createRaisedBevelBorder(),"Disks");
        titleDisks.setTitleJustification(TitledBorder.LEFT);
        DrivesPanel.setBorder(titleDisks);
        DrivesPanel.setName("");
        drivesScrollPane.setToolTipText("Scroll Pane");
        drivesScrollPane.setName("drivesTable");
        drivesTable.setModel(driveTModel);
        drivesTable.setToolTipText("Scroll Pane");
        drivesTable.setShowHorizontalLines(false);
        drivesTable.setShowVerticalLines(false);
        drivesScrollPane.setViewportView(drivesTable);

        chBoxLocalDrives.setText("Local Drives");
        chBoxLocalDrives.setToolTipText("Selects all local drivces");
        chBoxLocalDrives.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        chBoxLocalDrives.setMargin(new java.awt.Insets(0, 0, 0, 0));
        chBoxLocalDrives.setName("localDrives");

        chBoxRemovableDrives.setText("Removable Drives");
        chBoxRemovableDrives.setToolTipText("Select all removable drives");
        chBoxRemovableDrives.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        chBoxRemovableDrives.setMargin(new java.awt.Insets(0, 0, 0, 0));
        chBoxRemovableDrives.setName("removableDrives");

        buttonSelectAllDrives.setText("Select All");
        buttonSelectAllDrives.setToolTipText("Selects all drives");
        buttonSelectAllDrives.setName("selectAllDrives");

        buttonDeselectAllDrives.setText("Deselect All");
        buttonDeselectAllDrives.setName("deselectAllDrives");

        javax.swing.GroupLayout DrivesPanelLayout = new javax.swing.GroupLayout(DrivesPanel);
        DrivesPanel.setLayout(DrivesPanelLayout);
        DrivesPanelLayout.setHorizontalGroup(
            DrivesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, DrivesPanelLayout.createSequentialGroup()
                .addGap(37, 37, 37)
                .addComponent(drivesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 368, Short.MAX_VALUE)
                .addGap(66, 66, 66)
                .addGroup(DrivesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(buttonDeselectAllDrives, javax.swing.GroupLayout.DEFAULT_SIZE, 103, Short.MAX_VALUE)
                    .addComponent(chBoxRemovableDrives, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(chBoxLocalDrives)
                    .addComponent(buttonSelectAllDrives, javax.swing.GroupLayout.DEFAULT_SIZE, 103, Short.MAX_VALUE))
                .addGap(93, 93, 93))
        );
        DrivesPanelLayout.setVerticalGroup(
            DrivesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, DrivesPanelLayout.createSequentialGroup()
                .addGap(29, 29, 29)
                .addGroup(DrivesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(drivesScrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 214, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, DrivesPanelLayout.createSequentialGroup()
                        .addComponent(chBoxLocalDrives)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(chBoxRemovableDrives)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 126, Short.MAX_VALUE)
                        .addComponent(buttonSelectAllDrives)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonDeselectAllDrives)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
                .addGap(30, 30, 30))
        );

        FilesPanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        TitledBorder titleFiles=BorderFactory.createTitledBorder(BorderFactory.createRaisedBevelBorder(),"Files & Folders");
        titleFiles.setTitleJustification(TitledBorder.LEFT);
        FilesPanel.setBorder(titleFiles);
        FilesPanel.setName("");
        buttonAdd.setText("Add...");
        buttonAdd.setName("buttonAdd");

        buttonDelete.setText("Remove");
        buttonDelete.setName("buttonDelete");

        buttonSelectAllFiles.setText("Select All");
        buttonSelectAllFiles.setName("buttonSelectAllFiles");

        buttonDeselectAllFiles.setText("Deselect All");
        buttonDeselectAllFiles.setName("buttonDeselectAllFiles");

        filesScrollPane.setToolTipText("Scroll Pane");
        filesScrollPane.setName("filesTable");
        filesTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        filesTable.setToolTipText("Scroll Pane");
        filesTable.setShowHorizontalLines(false);
        filesTable.setShowVerticalLines(false);
        filesScrollPane.setViewportView(filesTable);

        javax.swing.GroupLayout FilesPanelLayout = new javax.swing.GroupLayout(FilesPanel);
        FilesPanel.setLayout(FilesPanelLayout);
        FilesPanelLayout.setHorizontalGroup(
            FilesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(FilesPanelLayout.createSequentialGroup()
                .addGap(34, 34, 34)
                .addComponent(filesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 373, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(69, 69, 69)
                .addGroup(FilesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(buttonDelete, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE)
                    .addComponent(buttonSelectAllFiles, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE)
                    .addComponent(buttonDeselectAllFiles, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE)
                    .addComponent(buttonAdd, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE))
                .addGap(104, 104, 104))
        );
        FilesPanelLayout.setVerticalGroup(
            FilesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(FilesPanelLayout.createSequentialGroup()
                .addGap(25, 25, 25)
                .addGroup(FilesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(filesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 181, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(FilesPanelLayout.createSequentialGroup()
                        .addComponent(buttonAdd)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonDelete)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(buttonSelectAllFiles)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonDeselectAllFiles)))
                .addContainerGap(39, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout TargetTabLayout = new javax.swing.GroupLayout(TargetTab);
        TargetTab.setLayout(TargetTabLayout);
        TargetTabLayout.setHorizontalGroup(
            TargetTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, TargetTabLayout.createSequentialGroup()
                .addContainerGap(52, Short.MAX_VALUE)
                .addGroup(TargetTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(DrivesPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(FilesPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(34, 34, 34))
        );
        TargetTabLayout.setVerticalGroup(
            TargetTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, TargetTabLayout.createSequentialGroup()
                .addGap(22, 22, 22)
                .addComponent(DrivesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(25, 25, 25)
                .addComponent(FilesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(34, 34, 34))
        );
        kkScanner_Tabber.addTab("Scan Targets", TargetTab);

        textArea.setColumns(20);
        textArea.setEditable(false);
        textArea.setRows(5);
        textAreaScrollPane.setViewportView(textArea);

        javax.swing.GroupLayout ScanningTabLayout = new javax.swing.GroupLayout(ScanningTab);
        ScanningTab.setLayout(ScanningTabLayout);
        ScanningTabLayout.setHorizontalGroup(
            ScanningTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ScanningTabLayout.createSequentialGroup()
                .addGap(27, 27, 27)
                .addComponent(textAreaScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 701, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(29, Short.MAX_VALUE))
        );
        ScanningTabLayout.setVerticalGroup(
            ScanningTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ScanningTabLayout.createSequentialGroup()
                .addGap(31, 31, 31)
                .addComponent(textAreaScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 544, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(32, Short.MAX_VALUE))
        );
        kkScanner_Tabber.addTab("Scanning Log", ScanningTab);

        scanButton.setText("Scan");

        stopButton.setText("Stop");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(kkScanner_Tabber, javax.swing.GroupLayout.DEFAULT_SIZE, 762, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addGap(250, 250, 250)
                .addComponent(scanButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(30, 30, 30)
                .addComponent(stopButton, javax.swing.GroupLayout.PREFERRED_SIZE, 99, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(283, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(kkScanner_Tabber, javax.swing.GroupLayout.PREFERRED_SIZE, 635, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(21, 21, 21)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(scanButton, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(stopButton, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE))
                .addContainerGap(20, Short.MAX_VALUE))
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    /**
     * @param args the command line arguments
     */
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel DrivesPanel;
    private javax.swing.JPanel FilesPanel;
    private javax.swing.JPanel ScanningTab;
    private javax.swing.JPanel TargetTab;
    private javax.swing.JButton buttonAdd;
    private javax.swing.JButton buttonDelete;
    private javax.swing.JButton buttonDeselectAllDrives;
    private javax.swing.JButton buttonDeselectAllFiles;
    private javax.swing.JButton buttonSelectAllDrives;
    private javax.swing.JButton buttonSelectAllFiles;
    private javax.swing.JCheckBox chBoxLocalDrives;
    private javax.swing.JCheckBox chBoxRemovableDrives;
    private javax.swing.JScrollPane drivesScrollPane;
    private javax.swing.JTable drivesTable;
    private javax.swing.JScrollPane filesScrollPane;
    private javax.swing.JTable filesTable;
    private javax.swing.JTabbedPane kkScanner_Tabber;
    private javax.swing.JButton scanButton;
    private javax.swing.JButton stopButton;
    private javax.swing.JTextArea textArea;
    private javax.swing.JScrollPane textAreaScrollPane;
    // End of variables declaration//GEN-END:variables
    JFileChooser filesChooser;
    Object[][] drivesData;
    Object[][] filesData;
    LinkedList filesList;
    commonTableModel driveTModel;
    
    static Vector<String> targets;
    
    class chBoxListener implements ItemListener{
        
        public void itemStateChanged(ItemEvent event){
            
            int i;
            
            JCheckBox chBox = (JCheckBox)(event.getSource());
            for(i=0;i<drivesData.length;i++){
                if(chBox.getName().equals("localDrives") && drivesData[i][2].equals("Hard Disk Drive") ){
                    drivesData[i][0]=(event.getStateChange()==ItemEvent.SELECTED )?true:false;
                } else if(chBox.getName().equals("removableDrives") && (  drivesData[i][2].equals("Removable Drive")
                ||  drivesData[i][2].equals("CD ROM Drive")  )   ){
                    drivesData[i][0]=( event.getStateChange()==ItemEvent.SELECTED )?true:false;
                }
                
            }
            drivesTable.repaint();
            
        }
    }
    
    class drivesButtonListener implements ActionListener{
        
        public void actionPerformed(ActionEvent event){
            
            int i;
            
            JButton button = (JButton)(event.getSource());
            
            for(i=0;i<drivesData.length;i++){
                if(button.getName().equals("selectAllDrives")){
                    drivesData[i][0]=true;
                } else if(button.getName().equals("deselectAllDrives")){
                    drivesData[i][0]=false;
                }
                
            }
            
            drivesTable.repaint();
            
            
            
        }
    }
    
    class AddDeleteButtonListener implements ActionListener {
        
        public void actionPerformed(ActionEvent event) {
            JButton button = (JButton)(event.getSource());
            if(button.getName().equals("buttonAdd")){
                JPanel parentPanel = (JPanel)(((JButton)event.getSource()).getParent());
                filesChooser.showDialog(parentPanel,"Select");
            } else if(button.getName().equals("buttonDelete")){
                //System.out.println("\n\nSel Row Count : "+filesTable.getSelectedRowCount()+"\n");
                if(filesTable.getSelectedRowCount()>0 ){
                    commonTableModel model = (commonTableModel)(filesTable.getModel());
                    //System.out.println(filesTable.getModel().getClass());
                    
                    if(model.deleteRow(filesTable.getSelectedRows())){
                        filesTable.setModel(new DefaultTableModel(null,new Object[]{"Serial","","List Of Files"}));
                        initFilesTableProperties(filesTable);
                    }
                    
                    filesTable.clearSelection();
                    filesTable.repaint();
                    
                }
            }
        }
    }
    
    class filesButtonListener implements ActionListener{
        public void actionPerformed(ActionEvent event){
            if(filesTable.getRowCount()!=0){
                JButton button = (JButton)(event.getSource());
                int i;
                boolean option = ((button.getName().compareTo("buttonSelectAllFiles")==0)?true:false);
                commonTableModel model=(commonTableModel)(filesTable.getModel());
                for(i=0;i<filesTable.getRowCount();i++){
                    model.setFileSelected(i,option);
                }
                filesTable.repaint();
            }
        }
    }
    
    class TableSelectionListener implements ListSelectionListener{
        
        TableSelectionListener(){
            
        }
        public void valueChanged(ListSelectionEvent event){
            if (event.getValueIsAdjusting()) return;
            
            ListSelectionModel selModel =
                    (ListSelectionModel)event.getSource();
            
            if(!selModel.isSelectionEmpty()){
                System.out.println("Selected Row : "+selModel.getMinSelectionIndex());
            }
            
        }
    }
    
    class scanButtonListener implements ActionListener{
        
        JDialog window;
        public scanButtonListener(JDialog window){
            this.window=window;
        }
        public void actionPerformed(ActionEvent event){
            
            System.out.println("scan button press action performed");
            final JButton button = (JButton)(event.getSource());
            
            //Raises an error if no targets are specified.
            if(getTargets()==null){
                JOptionPane.showMessageDialog(button.getParent() , "No Targets Specified", "Error !", JOptionPane.ERROR_MESSAGE);
                return ;
            } else{
                button.setEnabled(false);
                targets=getTargets();
                System.out.println("Printing from within event listner : " + targets);
                kkScanner_Tabber.setSelectedIndex(1);
                
                
                //Creates a separate thread to take care of the scanning of the targets in the background
                
                bgWorker=new ScanManager<Integer,Object>(window);
                stopButton.addActionListener(new stopButtonListener(bgWorker));
                bgWorker.execute();
                
            }
        }
    }
    
    
    class stopButtonListener implements ActionListener{
        SwingWorker<Integer,Object> bgWorker;
        public stopButtonListener(SwingWorker<Integer,Object> bgWorker){
            this.bgWorker=bgWorker;
        }
        public void actionPerformed(ActionEvent event){
            bgWorker.cancel(true);
        }
    }
    
    
    
    private void initScan(Vector<String> targets){
        for(int i=0;i<targets.size();i++)
            blastMalware(new java.io.File(targets.get(i)));
    }
    
    //------------VIRUS DETECTOR-------------------------------------
    
    private void blastMalware(java.io.File item){
        int i;
        if(item.isDirectory()){
            //System.out.println("\n"+item.getAbsolutePath()+"\n");
            java.io.File filesList[]=item.listFiles();
            if(filesList!=null){
                for(i=0;i<filesList.length;i++){
                    blastMalware(filesList[i]);
                }
            }
        } else if(item.isFile()){
            System.out.println(item.getAbsolutePath());
            textArea.append("\n"+item.getAbsolutePath());
            
            String virName=isMaliciousJ(item.getAbsolutePath());
            
            /*//DLL call has returned an error
             if(virName.equals("-1"))
                //throw an exception here
             */
            
            //Checking if no virus was detected i.e if isMaliciousJ returns "0"
            if(!virName.equals("0")){
                
                textArea.append("\nVirus Detected : "+virName+"\n");
            }
            //System.out.println(isMaliciousJ(item.getAbsolutePath()));
            updateTextArea();
        }
    }
//------------------------------------------------------------------
    private void updateTextArea(){
        Runnable setScanAreaContent = new Runnable() {
            public void run() {
                textArea.setCaretPosition(textArea.getDocument().getLength());
            }
        };
        SwingUtilities.invokeLater(setScanAreaContent);
    }
    
    class ScanManager<E,T> extends SwingWorker{
        JDialog window;
        public ScanManager(JDialog window){
            this.window=window;
        }
        public Integer doInBackground(){
            
            textArea.setText("") ;
            
            System.out.println("Printing from within doInBackground() : "+targets);
            //Creates a SimpleDateFormat object to format the date to MM/dd/yyyy HH:mm:ss
            //A Date class object represents the number of milliscenonds since Jan 1,1970,00:00:00 GMT
            String currDate = (new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")).format(new Date());
            //Appending to text area in the window.
            textArea.append("Date & Time : "+currDate+"\n\n");
            //Appending to text area in the window.
            textArea.append("\nLoading Killer Kitty Signatures.....");
            //updates the text area on the screem
            updateTextArea();
            
            try{
                //----------------Loads the DLL that provides the core functionalities for KillerKitty------------
                System.loadLibrary("KillerKitty");
                initializeJ();
                //------------------------------------------------------------------------------------------------
            } catch(UnsatisfiedLinkError e){
                //The DLL file cannot be loaded.
                System.out.println("Unable to load the DLL\n"+e);
                //Appending error message to text area in the window.
                textArea.append("Failed");
                JOptionPane.showMessageDialog(window , "Unable to load KillerKitty.dll", "Error !", JOptionPane.ERROR_MESSAGE);
                scanButton.setEnabled(true);
                kkScanner_Tabber.setSelectedIndex(0);
                return -1;
            }
            
            //Appending to text area in the window.
            textArea.append("Done");
            textArea.append("\n\nScanning Initiated\n\n");
            
            //updates the text area on the screem
            updateTextArea();
            
            //------------Scans the targets---------------------
            for(String target : targets){
                if(!isCancelled())
                    blastMalware(new java.io.File(target));
                else{
                    System.out.println("Breaking ! ");
                    JOptionPane.showMessageDialog(window,"Scanning process was interrupted by the user","Warning ! ",JOptionPane.WARNING_MESSAGE);
                    return 0;
                }
            }
            //---------------------------------------------------
            
            //Creates a SimpleDateFormat object to format the date to MM/dd/yyyy HH:mm:ss
            //A Date class object represents the number of milliscenonds since Jan 1,1970,00:00:00 GMT
            currDate = (new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")).format(new Date());
            //Appending to text area in the window.
            textArea.append("\n\nDate & Time : "+currDate+"\n\n");
            //Updating the text area on the screen
            updateTextArea();
            
            //Creates a report of the scan
            java.io.BufferedWriter reportWtr;
            try{
                //Changing date formatting so that it satisfies free of OS' file naming constraints
                currDate=currDate.replace('/','-').replace(':','.');
                String reportName=System.getProperty("user.dir")+"\\ScanReport_"+currDate+".txt";
                reportWtr=new java.io.BufferedWriter(new java.io.FileWriter(reportName));
                reportWtr.write(textArea.getText());
                reportWtr.close();
                JOptionPane.showMessageDialog(window,"Scan Completed Successfully.\nA Scan Report has been saved at : "+reportName,"Message",JOptionPane.INFORMATION_MESSAGE);;
            } catch(java.io.IOException e){
                System.out.println("Cannot create report !");
                JOptionPane.showMessageDialog(window,"Couldnot create report ","Error !",JOptionPane.ERROR_MESSAGE);
            }
            textArea.append("\nScanning completed successfully ! ");
            //Returning 1, indicating a successful scan of the targets
            return 1;
        }
        
        public void done(){
            //The Scan button is released as the scanning was completed successfully.
            scanButton.setEnabled(true);
            
        }
        
    }
}






class cellRenderer extends JLabel implements TableCellRenderer{
    
    cellRenderer(){
        
    }
    
    public Component getTableCellRendererComponent(
            JTable table, Object value,
            boolean isSelected, boolean hasFocus,
            int row, int column) {
        setToolTipText(value.toString());
        //this.setHorizontalTextPosition(SwingConstants.CENTER);
        setText(value.toString());
        
        return this;
        
    }
}



